﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using SolarWinds.Helpers;
using SolarWinds.Shapes;

namespace SolarWinds.Logic
{
    class AsteroidField : DrawableComponentManager
    {
        private float mAsteroidRate;

        public AsteroidField(Game game) : base(game)
        {
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            
            // generate asteroids
            var elapsedTime = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            mAsteroidRate -= elapsedTime;
            if (mAsteroidRate < 0.0f)
            {
                var asteroidPosition = new Vector3(RandomHelper.RandomBetween(-200, 200), 0, 200);
                float asteroidSpeed = RandomHelper.RandomBetween(100, 200);
                var asteroidDirection = new Vector3(RandomHelper.RandomFloat2(), 0.0f, RandomHelper.RandomFloat2());
                var asteroidSize = Vector3.One * RandomHelper.RandomBetween(0.1f, 0.3f);

                var asteroid = new AsteroidShape(Game)
                {
                    Position = asteroidPosition,
                    Direction = (-Vector3.UnitZ * asteroidSpeed + asteroidDirection),
                    Scale = asteroidSize,
                    Spin = RandomHelper.RandomVector3() * 0.001f
                };
                Components.Add(asteroid);

                mAsteroidRate = 200.0f;
            }

            // check for asteroids that left the screen
            var toBeRemoved = new List<IGameComponent>();
            foreach (IGameComponent component in Components)
            {
                var shape = (AsteroidShape) component;

                Matrix bsWorld = Matrix.CreateScale(shape.BoundingSphere.Radius) * shape.World;

                // Precalculate in shape
                BoundingSphere worldBoudningSphere = shape.BoundingSphere.Transform(bsWorld);

                if (SolarWindsGame.Camera.ViewFrustum.Contains(worldBoudningSphere) == ContainmentType.Disjoint ||
                    shape.Killed)
                {
                    toBeRemoved.Add(shape);
                }
            }

            foreach (IGameComponent component in toBeRemoved)
            {
                Components.Remove(component);

                var asteroid = component as AsteroidShape;
                if (asteroid != null) asteroid.Dispose();
            }
        }
    }
}
